package com.black.utils.file.compress.jar.entity;

import lombok.Getter;
import lombok.Setter;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author ylx
 */
@Getter
@Setter
public class ClassInfo extends JavaInfo {
    private int version;
    private String superName;
    private final List<String> interfaces;
    private final Map<String, FieldInfo> fields = new HashMap<>();
    private final Map<String, MethodInfo> methods = new HashMap<>();

    public ClassInfo(String name) {
        this(ACC_PUBLIC, 0, name, null, null, null);
    }

    public ClassInfo(int version, int access, String name, String signature, String superName, String[] interfaces) {
        super(name);
        this.version = version;
        this.access = access;
        this.name = name;
        this.signature = signature;
        this.superName = superName;
        this.interfaces = Arrays.asList(interfaces);
    }

    public void addField(String name, FieldInfo field) {
        this.fields.put(name, field);
    }

    public void addMethod(String name, String desc, MethodInfo method) {
        this.methods.put(name + desc, method);
    }

    public boolean isClass(String interfaceName) {
        interfaceName = interfaceName.replaceAll("\\.", "/");
        return interfaces.contains(interfaceName) || superName.equals(interfaceName) || name.equals(interfaceName);
    }

    public boolean hasMethod(String name) {
        return methods.values().stream().map(MethodInfo::getName).anyMatch(n -> n.equals(name));
    }

    public List<MethodInfo> getMethods(String methodName) {
        return methods.values().stream().filter(m -> m.getName().equals(methodName)).collect(Collectors.toList());
    }

    public List<ClassInfo> getInheritedClasses(JarInfo jarInfo) {
        List<ClassInfo> inheritedClasses = new ArrayList<>();
        ClassInfo currentClass = this;
        while (currentClass != null) {
            inheritedClasses.add(currentClass);
            currentClass = currentClass.superName != null ? jarInfo.getClass(currentClass.superName) : null;
        }
        return inheritedClasses;
    }

    /**
     * 从完整类名中提取包名
     *
     * @param className 完整类名
     * @return 包名
     */
    public static String getPackageName(String className) {
        if (className==null || className.isEmpty()) {
            return "";
        }
        int lastSlash = className.lastIndexOf('.');
        if (lastSlash > 0) {
            return className.substring(0, lastSlash);
        }
        return "";
    }

    /**
     * 从完整类名中提取简单类名
     *
     * @param className 完整类名
     * @return 简单类名
     */
    public static String getSimpleClassName(String className) {
        if (className==null || className.isEmpty()) {
            return "";
        }
        int lastSlash = className.lastIndexOf('.');
        if (lastSlash > 0 && lastSlash < className.length() - 1) {
            return className.substring(lastSlash + 1);
        }
        return className;
    }
}
